<?php


namespace backend\modules\tool\DataSource\EventLoop;


use backend\modules\tool\DataSource\Config\Config;
use backend\modules\tool\DataSource\Log\Log;
use backend\modules\tool\DataSource\Log\PidRecord;
use backend\modules\tool\DataSource\Queue\Queue;
use backend\modules\tool\DataSource\Task\command\command;
use backend\modules\tool\DataSource\Task\command\CommandFaced;
use backend\modules\tool\DataSource\Task\command\LinuxCommand;
use backend\modules\tool\DataSource\Task\command\WindowsCommad;
use backend\modules\tool\helpers\functions;
use backend\modules\tool\models\DataSourceTask;
use console\modules\datasource\models\DataSourceProvider;
use yii\db\Expression;
use yii\db\Query;

class Main
{
    protected $channel_name="wait_run_task";
    /**
     * @var Queue
     */
    protected $queue;
    /**
     * @var command
     */
    protected $commnd;
    protected $log;
    protected $pid_record;
    const max_process_num_main="max_process_num_main===>";
    public function __construct()
    {
        $this->log=Log::SingleTon("main");
        $queue_name=Config::$driver["queue"];
        /**
         * @var Queue
         */
        $this->commnd=CommandFaced::getDirver();
        $this->queue=new $queue_name();
        $this->pid_record=PidRecord::SingleTon("main");

        if($this->pid_record->IsRun()){
            echo "主进程已经在运行中无需再次启动";
            exit();
        }
        $this->pid_record->recordMyPid();
        $this->log->write("主进程开始运行".date("Y-m-d H:i:s"));
    }
    public static function getMax(){
        return \Yii::$app->cache->getOrSet(self::max_process_num_main,function (){
            return 30;//默认最大进程数量30
        });
    }
    public static function setMax(int $num):void{
        \Yii::$app->cache->set(self::max_process_num_main,$num);
    }
    public function Run(){
        while(true){
//            echo microtime(true).PHP_EOL;
            $result=DataSourceTask::find()
                ->where(new Expression("pid='' or pid is null"))
                ->andWhere(["<=","run_time",date("Y-m-d H:i:s")])
                ->andWhere(['status'=>1])//设置可执行的数据
                ->andWhere(new Expression("run_num='forever' or run_num>0"))
                ->all();
            foreach ($result as $item){
                $item->nextTick();
                $this->queue->push($this->channel_name,$item->id);
            }
            while (!empty($data=$this->queue->pop($this->channel_name))){
                $max=self::getMax();
                $running=PidRecord::getRunningProcess();
                while ($running>=$max){
                    $this->log->write("最大进程:{$max}"." 当前运行进程:{$running} 正在等待资源释放==>");
                    sleep(2);
                    continue;
                }
//                print_r($data);die();
//                echo "run";
                echo "yii tool/index {$data}";
                $this->log->write("执行命令==>"."yii tool/index {$data} ".date("Y-m-d H:i:s"));
                $this->commnd->run("yii tool/index {$data}");
            }
            sleep(2);
        }
    }
}